public without sharing class ContractProductAdjustController {
    public List<ContractProductBean> cpList { get; set; }///已经有的

    public List<ContractProductBean> selectCPList {get;set;}//选择的需要调价的


    public Account acc { get; private set; }

    
    public String accId { get;  set; }
    
    public List<SelectOption> products {set;get;}//可选产品;
    
    public String serialNo {set;get;}//货号
    
    public List<SelectOption> brands {set;get;}//品牌
    
    public List<SelectOption> categorys {set;get;}// 一级分类
    
    public String product {set;get;}//可选产品;
    
    public String brand {set;get;}//品牌
    
    public String category {set;get;}// 一级分类

    public User u ;

    public String adjustId;

    public Boolean isSuccess {get;set;}//是否保存成功

    public AdjustPrice__c ap ;

    public String apId {get; set;}///合同调价id;

    public  List<AdjustPriceProduct__c> oldAjustList;

    public Boolean isApproval {get;set;}// 是否审核中

    public String msg {get;set;}//错误消息

    public Boolean isShowLastAverge {get;set;}//是否显示上月平均价

    public List<SelectOption> lastPriceOption {get;set;}//高于上月平均价、低于上月平均价、上月平均为空

    public String lastPriceSelectedOption {get;set;}//选择的筛选类型

    public Integer tableHeight {get;set;}///表格高度


    public ContractProductAdjustController(ApexPages.StandardController con) {
        cpList = new List<ContractProductBean>();
        selectCPList = new List<ContractProductBean>();
        ap = new AdjustPrice__c();
        oldAjustList = new List<AdjustPriceProduct__c>();
        // conId = System.currentPageReference().getParameters().get('conid');
        accId = System.currentPageReference().getParameters().get('accid');

        adjustId = System.currentPageReference().getParameters().get('id');
        lastPriceOption = new List<SelectOption>();
        lastPriceOption.add(new SelectOption('0','--请选择筛选条件--'));
        lastPriceOption.add(new SelectOption('1','高于上月平均价'));
        lastPriceOption.add(new SelectOption('2','低于上月平均价'));
        lastPriceOption.add(new SelectOption('4','等于上月平均价'));

        lastPriceOption.add(new SelectOption('3','上月平均为空'));
        acc = new Account();
    }

    public void init() {
        // 合同
        // con = [select Id, Name, Account__c from Contract__c where Id = :conId];
        

         u = [select SubCompany__c from User where Id = :UserInfo.getUserId()];
         isShowLastAverge = u.SubCompany__c == '四川省迈克实业有限公司';
         if(Test.isRunningTest()){
            u.SubCompany__c= '四川省迈克实业有限公司';
         }
        if (accId!=null) {//新建
           
           acc = [select Id, Name,RecordType.DeveloperName from Account where Id = :accId];
             // 新建调价合同
            ap.Account__c = acc.Id;
            ap.Status__c = '草案中';
            apId = accId;
            Id rt = null ;
            if ( acc.RecordType.DeveloperName == 'TerminalCustomer' ) {
                rt = Utils.getRecordTypeIdByDevNameAndObjName('TerminalCustomerAdjustPrice','AdjustPrice__c');
            }else if(acc.RecordType.DeveloperName == 'Dealer'){
                 rt = Utils.getRecordTypeIdByDevNameAndObjName('DealerAdjustPrice','AdjustPrice__c');
   
            } 
            if(rt != null)ap.RecordTypeId = rt;
        }else if (adjustId != null ) {//编辑
            getContractProductAdjustDetail();
           ap = [select Id, Account__r.Name,Account__c,Status__c from AdjustPrice__c where Id = :adjustId];
           acc.Name = ap.Account__r.Name;
           acc.Id = ap.Account__c;
           accId = ap.Account__c;

            apId = adjustId;

        } 
        isApproval =  (ap.Status__c == '已提交' || ap.Status__c == '已批准') ? true : false;
         search();
        
           
        Set<String> ps = new Set<String>();
        Set<String> bs = new Set<String>();
        Set<String> cas = new Set<String>();
        for(ContractProductBean cp : cpList){
         if(cp.cp.Product__r.Name != null)ps.add(cp.cp.Product__r.Name);
            if(cp.cp.Product__r.Brand__c != null)bs.add(cp.cp.Product__r.Brand__c);
            if(cp.cp.Product__r.Category1__c != null)cas.add(cp.cp.Product__r.Category1__c);
        }
        products = optionHandler(ps);
        brands = optionHandler(bs);
        categorys = optionHandler(cas);
        tableHeight = selectCPList.size() < 10 ? 150 + selectCPList.size()*22 : 400;

    }
    public void getContractProductAdjustDetail(){

        Schema.DescribeSobjectResult m = AdjustPriceProduct__c.sObjectType.getDescribe();
        Map<String, Schema.SObjectField> fieldMap = m.fields.getMap();
          String sql = 'select ';
        String fields = '';
        for (String field : fieldMap.keySet()) {
            if (fields.length() > 0) {
                fields += ', '; 
            }
            fields += field;
        }
        sql += fields;

        sql += ',AdjustTo__r.Product__r.NCCode__c, AdjustTo__r.Product__r.Name, AdjustTo__r.Product__r.Brand__c, AdjustTo__r.Product__r.Spec__c, AdjustTo__r.Product__r.Unit__c, ';
        sql += 'AdjustTo__r.Product__r.Category1__c,AdjustTo__r.Product__r.swjhdj__c,AdjustTo__r.Product__r.SerialNo__c,AdjustTo__r.Contract__r.Name,AdjustTo__r.Product__r.bggsjhdj__c,';
        sql += 'AdjustTo__r.Type__c,AdjustTo__r.Company__c, AdjustTo__r.Product__c,AdjustTo__r.UnitPrice__c,AdjustTo__r.SalesPrice__c,AdjustTo__r.Contract__r.CompanyControls__c ';
        sql += ' from AdjustPriceProduct__c where AdjustPrice__c = \''+adjustId+'\'';
         oldAjustList= Database.query(sql);
        
         Set<Id> proset = new Set<Id>();
        for(AdjustPriceProduct__c ap : oldAjustList){
            proset.add(ap.AdjustTo__r.Product__c);
        }
        Map<String,AveragePrice__c> lastMap =  getLastAveragePrice(proset);

       for(AdjustPriceProduct__c ap : oldAjustList){
            selectCPList.add(new ContractProductBean(ap,lastMap.get(ap.AdjustTo__r.Product__c+ap.AdjustTo__r.Contract__r.CompanyControls__c)));
        }

        System.debug('==='+selectCPList);



    }
    ///交换 
    public void exchange (){
        ///去重
        Set<Id>  exitendIdSet= new Set<Id>();
        //保存原来的
        List<ContractProductBean> temp = new List<ContractProductBean>();

        for ( ContractProductBean cpb: selectCPList) {
            if (cpb.chk == false){
                temp.add(cpb);
                exitendIdSet.add(cpb.cpId);

            }

        }
        selectCPList.clear();
        selectCPList.addAll(temp);

        ///添加新选择的
        for ( ContractProductBean cpb: cpList) {
            if (cpb.chk == true && !exitendIdSet.contains(cpb.cpId)){
               
                cpb.chk = false;
                 selectCPList.add(cpb.clone());
            }
        }

        tableHeight = selectCPList.size() < 10 ? 150 + selectCPList.size()*22 : 400;

    }
    ///检索
    public void search(){
        String sql = 'select ';

        try{
        // 合同产品（只选试剂）s
        Schema.DescribeSobjectResult m = ContractProduct__c.sObjectType.getDescribe();
        Map<String, Schema.SObjectField> fieldMap = m.fields.getMap();
        
        String fields = '';
        for (String field : fieldMap.keySet()) {
            if (fields.length() > 0) {
                fields += ', '; 
            }
            fields += field;
        }
        sql += fields;
        sql += ' ,Product__r.NCCode__c, Product__r.Name, Product__r.Brand__c, Product__r.Spec__c, Product__r.Unit__c, Product__r.swjhdj__c,Product__r.SerialNo__c,Contract__r.Name';
        sql += ',Product__r.Category1__c,Contract__r.CompanyControls__c  ';
        sql += ' from ContractProduct__c where Contract__r.Account__c = \'' + accId + '\' and Contract__r.CompanyControls__c = \'' + u.SubCompany__c + '\' and Product__r.Category0__c !=\'仪器\' and Contract__r.Status__c =\'已生效\' and Contract__r.Stopped__c = false ';
     String whereStr = '';
        if (String.isBlank(product) == false) {
            whereStr += ' and Product__r.Name like \'%' + product + '%\'';
        }
        if (String.isBlank(brand) == false) {
            whereStr += ' and  Product__r.Brand__c like \'%' + brand + '%\'';
        }
        if (String.isBlank(serialNo) == false) {
            whereStr += ' and  Product__r.SerialNo__c like \'%' + serialNo + '%\'';
        }
         if (String.isBlank(category) == false) {
            whereStr += ' and  Product__r.Category1__c like \'%' + category + '%\'';
        }
            sql +=  whereStr  + ' order by Id  limit 500';
      
        List<ContractProduct__c> tempList= Database.query(sql);
        cpList.clear();

        Set<Id> proset = new Set<Id>();
        for(ContractProduct__c cp : tempList){
            proset.add(cp.Product__c);
        }
        Map<String,AveragePrice__c> lastMap =  getLastAveragePrice(proset);

        System.debug('++'+lastMap);
       for(ContractProduct__c cp : tempList){

            AveragePrice__c ap = lastMap.get(cp.Product__c+cp.Contract__r.CompanyControls__c);

            //if(lastPriceSelectedOption == '0');///没选择
            if(lastPriceSelectedOption == '1' && (ap == null || ap.AveragePrice__c >= cp.SalesPrice__c ))continue;///高于
            if(lastPriceSelectedOption == '2' && (ap == null ||  ap.AveragePrice__c <= cp.SalesPrice__c ))continue;///低于
            if(lastPriceSelectedOption == '3' && ap != null ) continue;///为空
            if(lastPriceSelectedOption == '4' && (ap == null ||  ap.AveragePrice__c != cp.SalesPrice__c ))continue;///低于

            cpList.add(new ContractProductBean(cp,ap));
        }


        System.debug('+++' + sql);

        System.debug('+++' + cpList);
        }catch(Exception e){
           ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, e.getMessage() + sql));
 
        }
    }
    private List<SelectOption>  optionHandler (Set<String> s){
       List<SelectOption> ss = new List<SelectOption>();
       ss.add(new SelectOption('', System.Label.Option_None));

        for (String str : s){
        ss.add(new SelectOption(str,str));
        }
        return ss;
    }

    ///获取上月平均价 
    private Map<String,AveragePrice__c> getLastAveragePrice(Set<Id> proset){
         /// 日期处理
        Integer m = Date.today().month(); //当前月份
        Integer y = Date.today().year();  //当前年份 
       ///取上月
         if(m == 1){
            m = 12 ;
            y -= 1;
        }else{
            m -= 1;
            
        }
        
        String  month = String.valueOf(m) + '月';
        String  year= String.valueOf(y) + '年';
        //上月平均价(元)
         Map<String ,AveragePrice__c>lastPs = new Map<String ,AveragePrice__c>();
         for(AveragePrice__c a : [select AveragePrice__c  ,Product__c,Company__c from AveragePrice__c where 
                                  Year__c =:year and Month__c =: month and Product__c in : proset and Company__c =:u.SubCompany__c]){
                     lastPs.put( a.Product__c + a.Company__c ,a);  
         }
         return lastPs;

    }
    public void save() {
        msg = '';
        if(isApproval == true) {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, '合同调价在'+ap.Status__c+'不能修改!' ));
            return;
        }
        if (selectCPList.size() == 0) {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, '没有选择调价明细!' ));
            return;
        }
        Savepoint sp = Database.setSavepoint();
        try {
          
            //ap.Name = acc.Name + '-价格调整-' + Utils.date2string(Date.today());
            upsert ap;
          System.debug('++++'+ ap);
       ///保存公司
       Set<String>companys = new Set<String>();
       ///保存产品
       Set<Id>products = new Set<Id>();
            
       for(ContractProductBean cp:selectCPList){
                companys.add(cp.company);
                products.add(cp.productId);
            
       }
            System.debug('++++'+companys);
            System.debug('++++'+products);

            ///带出价格体系中的价格
              ///公司低价(元) 应调整价格(元)
        Map<String ,Price__c> cp_prs = new Map<String,Price__c>();
        for (Price__c p : [select Product__c,Company__c,CompanyBottomPrice__c,HospitalBottomPrice__c,
                           InvoiceDealerPrice__c,AreaDealerPrice__c,MarketPrice__c,HospitalManagerPrice__c,InstCost__c
                           from Price__c where Product__c in: products and Company__c in:companys]){
                 cp_prs.put(p.Product__c + p.Company__c,p);  
           
        }
        
        /// 日期处理
        Integer m = Date.today().month(); //当前月份
        Integer y = Date.today().year();  //当前年份 
       ///取上月
         if(m == 1){
            m = 12 ;
            y -= 1;
        }else{
            m -= 1;
            
        }
        
        String  month = String.valueOf(m) + '月';
        String  year= String.valueOf(y) + '年';
        //上月平均价(元)
         Map<String ,AveragePrice__c>lastPs = new Map<String ,AveragePrice__c>();
         for(AveragePrice__c a : [select AveragePrice__c  ,Product__c,Company__c from AveragePrice__c where 
                                  Year__c =:year and Month__c =: month and Product__c in : products and Company__c in:companys]){
                     lastPs.put( a.Product__c + a.Company__c ,a);  
         }
         
            
            // 新建调价合同产品
            List<AdjustPriceProduct__c> adjustCpList = new List<AdjustPriceProduct__c>();
            //更新将调价的合同挂到合同调价对象下
            Set<String> conSet = new Set<String>();
            List<Contract__c>  conList= new List<Contract__c>();
            System.debug(cp_prs);

            msg = '';///错误消息
            for (ContractProductBean cp : selectCPList) {
                    AdjustPriceProduct__c app = new AdjustPriceProduct__c();
                    //app.Name = '价格调整-' + cp.Product__r.Name;
                    app.AdjustPrice__c = ap.Id;
                    app.AdjustTo__c = cp.cpId;
                    app.AdjustSalesPrice__c = cp.adjustSalesprice;
                    app.ProductLine__c = cp.prodLine;
                    app.OriginalPrice__c = cp.oralPrice;
                    app.Product__c = cp.productId;
                    System.debug(cp.productId + cp.company);
                    ///保存价格
                    if(cp_prs.containsKey(cp.productId + cp.company)){

                        Price__c p = cp_prs.get(cp.productId + cp.company);
                        app.swjhdj__c = cp.swjhdj ;///生物计划单价
                        app.InstCost__c =  p.InstCost__c;//成本价:
                        app.CompanyBottomPrice__c = p.CompanyBottomPrice__c;//公司低价
                        app.AreaDealerPrice__c = p.AreaDealerPrice__c;//区域经销商价
                        app.HospitalManagerPrice__c = p.HospitalManagerPrice__c;//终端指导价
                        app.InvoiceDealerPrice__c = p.InvoiceDealerPrice__c;//报单经销商价
                        app.HospitalBottomPrice__c = p.HospitalBottomPrice__c;//销售员低价
                    }else{

                        msg += '<p>'+cp.productName +'-'+cp.serialNo+'</p>';
                    }                       
                     AveragePrice__c a = lastPs.get(cp.productId + cp.company);

                    if(lastPs.containsKey(cp.productId + cp.company)){

                        app.LastMonthAveragePrice__c = a.AveragePrice__c;//上月平均价
                    }
                    conSet.add(cp.contractId);
                    adjustCpList.add(app);
                
            }
            ///如果没有价格体系则报错
            if(msg.length() > 0){
               // <div style="padding: 50px; line-height: 22px; background-color: #393D49; color: #fff; font-weight: 300;">
                msg = '<div style="padding: 20px;"><h2>这些产品没有价格体系,联系产品经理核实:</h2>' + msg +'</div>';
               //ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, '这些产品没有价格体系,联系产品经理核实:' + msg));
               return;
            }
            for (String con : conSet) {
               conList.add(new Contract__c(Id=con,RelatedContractPriceAdjustment__c=ap.Id));
 
            }
           if(oldAjustList.size() > 0) delete oldAjustList;     

            insert adjustCpList;
           if (conList.size()>0) update conList;
            apId = ap.Id;
            System.debug(apId);
            isSuccess = true;
            
        } catch (Exception e) {
            Database.rollback(sp);
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, e.getMessage()));
        }
        
    }
    public void adjustPirceByLastPrice(){

        for ( ContractProductBean cpb: selectCPList) {

           if(cpb.lastAvergePrice != null && cpb.lastAvergePrice != 0 ) cpb.adjustSalesprice = cpb.lastAvergePrice;
            //cpb.adjustSalesprice = 1111;
        }
    }

    public class ContractProductBean{
        public Boolean chk {get;set;}
        public ContractProduct__c cp {get;set;}
        public AdjustPriceProduct__c ap {get;set;}

        public String contractName {get;set;}//合同名称
        public String serialNo {get;set;}//货号
        public String productName {get;set;}//产品名称
        public String spec {get;set;}//规格
        public String brand {get;set;}//品牌
        public String type {get;set;}//类型
        public Decimal salesprice {get;set;}//合同产品报价
        public Decimal adjustSalesprice {get;set;}//合同产品调整价格
        public String productId {get;set;}//产品ID
        public String cpId {get;set;}//合同产品ID
        public String company {get;set;}//公司
        public Decimal swjhdj {get;set;}//生物计划单价
        public String unit {get;set;}//单位
        public Decimal unitprice {get;set;}//报价
        public String contractId {get;set;}//合同的ID
        public String prodLine {get;set;}//产品线
        public Decimal lastAvergePrice {get;set;}//上月平均价
        public Decimal oralPrice {get;set;}//原价

        public ContractProductBean(ContractProduct__c record,AveragePrice__c ap){
            chk = false;
            cp = record;
            contractName = record.Contract__r.Name ;
            serialNo = record.Product__r.SerialNo__c;
            productName = record.Product__r.Name;
            spec = record.Product__r.Spec__c ;
            brand = record.Product__r.Brand__c ;
            type = record.Type__c;
            salesprice = record.SalesPrice__c ;
            //adjustSalesprice = record.AdjustSalesPrice__c ;
            cpId = record.Id;
            productId = record.Product__c;
            company = record.Contract__r.CompanyControls__c;
            swjhdj = record.Product__r.swjhdj__c;
            unit = record.Product__r.Unit__c;
            unitprice = record.UnitPrice__c;
            contractId = record.Contract__c;
            prodLine = record.Product__r.Category1__c;
            lastAvergePrice = ap != null ? ap.AveragePrice__c : null;
            oralPrice = record.SalesPrice__c;

        }
        public ContractProductBean(AdjustPriceProduct__c record,AveragePrice__c ap){
            chk = false;
            cp = new ContractProduct__c();

            contractName = record.AdjustTo__r.Contract__r.Name ;
            serialNo = record.AdjustTo__r.Product__r.SerialNo__c;
            productName = record.AdjustTo__r.Product__r.Name;
            spec = record.AdjustTo__r.Product__r.Spec__c ;
            brand = record.AdjustTo__r.Product__r.Brand__c ;
            type = record.AdjustTo__r.Type__c;
            salesprice = record.AdjustTo__r.SalesPrice__c ;
            adjustSalesprice = record.AdjustSalesPrice__c ;
            cpId = record.AdjustTo__c;
            productId = record.AdjustTo__r.Product__c;
            company = record.AdjustTo__r.Contract__r.CompanyControls__c;
            swjhdj = record.AdjustTo__r.Product__r.swjhdj__c;
            unit = record.AdjustTo__r.Product__r.Unit__c;
            unitprice = record.AdjustTo__r.UnitPrice__c;
            contractId = record.AdjustTo__r.Contract__c;
            prodLine = record.AdjustTo__r.Product__r.Category1__c;
            lastAvergePrice = ap != null ? ap.AveragePrice__c : null;
            oralPrice = record.OriginalPrice__c;

            

        }

    }
    
}